package com.robinmouren.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.robinmouren.config.ThreadPoolConfig;
import com.robinmouren.constant.MessageConstant;
import com.robinmouren.constant.StatusConstant;
import com.robinmouren.context.BaseContext;
import com.robinmouren.dto.SplitRouteDto;
import com.robinmouren.entity.OrderInfo;
import com.robinmouren.entity.OrderStatus;
import com.robinmouren.entity.SplitRoute;
import com.robinmouren.entity.SplitRouteList;
import com.robinmouren.exception.NullInfoException;
import com.robinmouren.exception.NullOrderInfoException;
import com.robinmouren.mapper.SplitRouteMapper;
import com.robinmouren.service.ISplitRouteService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.robinmouren.utils.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Robinmouren
 * @since 2024-05-23
 */
@Service
public class SplitRouteServiceImpl extends ServiceImpl<SplitRouteMapper, SplitRoute> implements ISplitRouteService {


    @Autowired
    private OrderInfoServiceImpl orderInfoService;
    @Autowired
    private ThreadPoolTaskExecutor executor;
    @Autowired
    private RedisTemplate<String, List<OrderStatus>> redisTemplate;


    /**
     * 保存拆分后的路线信息
     *
     * @param dto
     */
    @Override
    public void saveRoute(SplitRouteDto dto) {

        String orderNumber = dto.getOrderNumber();
        List<SplitRouteList> route = dto.getRoute();

        // 获取订单id
        OrderInfo orderInfo = orderInfoService.getOne(new LambdaQueryWrapper<OrderInfo>()
                .eq(OrderInfo::getOrderNumber, orderNumber));
        Long id = orderInfo.getId();
        String originPlace = orderInfo.getOriginPlace();
        String destination = orderInfo.getDestination();

        // 判断是否已拆分，若已拆分，则先将拆分的信息删除
        List<SplitRoute> ifExistList = this.list(new LambdaQueryWrapper<SplitRoute>()
                .eq(SplitRoute::getOrderId, id));
        if(ifExistList.size() > 0){
            this.removeBatchByIds(ifExistList);
        }


        // TODO 处理时间信息

        // 排序
        AtomicInteger sort = new AtomicInteger(1);
        List<SplitRoute> list = new ArrayList<>();
        list.add(SplitRoute.builder()
                .orderId(id)
                .userId(BaseContext.getCurrentId())
                .outlets(StringUtils.partitionStringToGet(originPlace, 1))
                .address(StringUtils.partitionStringToGet(originPlace, 2))
                .sort(sort.getAndIncrement())
                .build());

        if(route.size() > 0){
            route.forEach(item -> {
                list.add(SplitRoute.builder()
                        .outlets(item.getOutlets())
                        .address(item.getAddress())
                        .orderId(id)
                        .sort(sort.getAndIncrement())
                        .userId(BaseContext.getCurrentId())
                        .build());
            });
        }

        list.add(SplitRoute.builder()
                .orderId(id)
                .userId(BaseContext.getCurrentId())
                .outlets(StringUtils.partitionStringToGet(destination, 1))
                .address(StringUtils.partitionStringToGet(destination, 2))
                .sort(sort.getAndIncrement())
                .build());

        this.saveBatch(list);

        // 开启线程池
        // 修改订单状态
        executor.execute(() -> {
            orderInfo.setStatus(StatusConstant.SPLIT_ROUTE);
            orderInfoService.updateById(orderInfo);
        });
        // 修改缓存中的状态
        executor.execute(() -> {
            // 将缓存中订单的状态信息修改
            List<OrderStatus> orderStatuses = redisTemplate.opsForValue().get(orderNumber);
            // 订单信息为空
            if (orderStatuses == null) {
                throw new NullOrderInfoException(MessageConstant.ORDER_IS_NULL);
            }
            OrderStatus.reviseList(orderStatuses, StatusConstant.SPLIT_ROUTE, LocalDateTime.now());
            // 重新将值存入
            redisTemplate.opsForValue().set(orderNumber, orderStatuses);
        });


    }


    /**
     * 根据订单号获取拆分后的路线信息
     * @param orderNumber
     * @return
     */
    @Override
    public List<SplitRouteList> getByNum(String orderNumber) {

        // 获取订单id
        OrderInfo orderinfo = orderInfoService.getOne(new LambdaQueryWrapper<OrderInfo>()
                .eq(OrderInfo::getOrderNumber, orderNumber));
        Long id = orderinfo.getId();

        // 获取拆分后的路线信息
        List<SplitRoute> list = this.list(new LambdaQueryWrapper<SplitRoute>()
                .eq(SplitRoute::getOrderId, id));
        if(list.size() < 1){
            throw new NullInfoException(MessageConstant.SPLIT_ROUTE_IS_NULL);
        }

        executor.execute(() -> {
            // 将缓存中订单的状态信息修改
            List<OrderStatus> orderStatuses = redisTemplate.opsForValue().get(orderNumber);
            // 订单信息为空
            if (orderStatuses == null) {
                throw new NullOrderInfoException(MessageConstant.ORDER_IS_NULL);
            }
            OrderStatus.reviseList(orderStatuses, StatusConstant.SPLIT_GOODS, LocalDateTime.now());
            // 重新将值存入
            redisTemplate.opsForValue().set(orderNumber, orderStatuses);
        });



        return list.stream().map(item -> {
            SplitRouteList splitRouteList = new SplitRouteList();
            BeanUtils.copyProperties(item, splitRouteList);
            return splitRouteList;
        }).collect(Collectors.toList());
    }
}

